use strict;

=head1 NAME

Svn support

=head1 VERSION

0.2

=head1 DESCRIPTION

Support for SVN repository

=head1 AUTHOR

Lubo Molent <lubomir.molent at gmail.com>

Copyright (c) 2007 Lubo Molent. All rights reserved.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

=cut



my $app  = Zim::GUI->current;
my $dir = $app->{repository}->{dir};


# do you have subversion tools installed?
&check_svn;

# check for new revision in SVN repository
$app->signal_connect(page_loaded => \&is_recent);

# Specify properties for the menu item
$app->{actions}->add_actions( [
	[	'SvnCheckout',		# Name - used below in xml
		'gtk-go-down',		# Stock icon name
		'SVN checkout',		# Menu text
		undef,			# Keybinding
		'Checkout zim root from SVN repository',	# Tooltip text
		\&on_SvnCheckout,	# Callback code
	],
	[	'SvnUpdate',		# Name - used below in xml
		'gtk-refresh',		# Stock icon name
		'SVN update',		# Menu text
		undef,			# Keybinding
		'Update zim root from SVN repository',	# Tooltip text
		\&on_SvnUpdate,	# Callback code
	],
	[	'SvnCommit',		# Name - used below in xml
		'gtk-apply',		# Stock icon name
		'SVN commit',		# Menu text
		undef,			# Keybinding
		'Commit zim root to SVN repository',	# Tooltip text
		\&on_SvnCommit,	# Callback code
	],
	[	'SvnImport',		# Name - used below in xml
		'gtk-go-up',		# Stock icon name
		'SVN import',		# Menu text
		undef,			# Keybinding
		'Import zim root to SVN repository',	# Tooltip text
		\&on_SvnImport,	# Callback code
	],
	[	'SvnCleanup',		# Name - used below in xml
		'gtk-clear',		# Stock icon name
		'SVN cleanup',		# Menu text
		undef,			# Keybinding
		'Cleanup SVN working copy',	# Tooltip text
		\&on_SvnCleanup,	# Callback code
	],
] );

# is current Zim repository under SVN?
&is_wc;


# Specify the menu layout
$app->{ui}->add_ui_from_string( q{
<ui>

	<menubar name='MenuBar'>
		<menu action='ToolsMenu'>
			<separator/>
			<menuitem action='SvnCommit'/>
			<menuitem action='SvnUpdate'/>
			<menuitem action='SvnImport'/>
			<menuitem action='SvnCheckout'/>
			<menuitem action='SvnCleanup'/>
			<separator/>
		</menu>
	</menubar>
</ui> } );



# Functionality goes below
#
# The functions on_MenuAction is called when the menu
# item is activated.
#


sub is_recent {
	my $url;
	my $local_revision = 0;
	my $revision = 0;
	my $page = $app->{page};
	my $rep = $page->{repository};
	return unless $rep->can('file');
	my $file = $rep->file( $page );
	my $filepath = $file->path;

	open(OUT,"svn info \"$filepath\" 2>&1|") ;
	while (<OUT>) {
		s/\n//;
		if (/^URL/) {
			$url = substr ("$_",4);
		}

		if (/^Last Changed Rev/) {
			$local_revision = substr ("$_",17);
		}
	}

	open(OUT,"svn info \"$url\" 2>&1|") ;
	while (<OUT>) {
		s/\n//;
		if (/^Last Changed Rev/) {
			$revision = substr ("$_",17);
		}
	}

	if ($local_revision != 0 && $revision != 0 && $local_revision < $revision) {
		$app->error_dialog("Version of this page in repository was updated.\nPlease update (Tools -> SVN update) your working copy.");
	}
}
	


sub check_svn {
	my $svn_test = system ("svn --version --quiet &>/dev/null");
	if ($svn_test) {
		$app->error_dialog(
				"Failed to load SVN plugin,\n".
				"do you have subversion utils installed?");
		$app->unplug('Subversion');
		return 1;
	}
}

sub is_wc {
	if (system("svn info $dir &>/dev/null")) {
	# if dir is not SVN working copy 
		$app->actions_set_sensitive(
				'SvnUpdate' => 0,
				'SvnCommit' => 0,
				'SvnCheckout' => 1,
				'SvnImport' => 1,
				'SvnCleanup' => 0
				);
		$app->message("Directory $dir is not SVN working copy")
	}
	# if dir is SVN working copy 
	else {
		$app->actions_set_sensitive( 
				'SvnCheckout' => 0,
				'SvnUpdate' => 1,
				'SvnCommit' => 1,
				'SvnImport' => 0,
				'SvnCleanup' => 1
				);
		$app->message("Directory $dir is SVN working copy")
	}
}

sub on_SvnCleanup {
	if (system ("svn cleanup $dir &>/dev/null")) {
		$app->error_dialog("Failed to cleanup SVN working copy $dir!");
	}
	else {
		&is_wc;
		$app->RBIndex();
	}
}


sub on_SvnCheckout {
	my $val; 
	my $url;
	my $username;
	my $password;

	$val = $app->run_prompt(
			'Enter SVN repository',
			['url','username','password'],
			{ url => ['SVN repository URL', 'string', 'http://'],
			username => ['Username', 'string', ''],
			password => ['Password', 'password', '']
			}
			);
	if ($val) {
		($url,$username,$password) = @$val;
		if (system ("svn co --username $username --password $password $url $dir &>/dev/null")) {
			$app->error_dialog("Failed to checkout SVN repository $url!");
		}
		else {
		&is_wc;
		$app->RBIndex();
		}

	}



}

sub on_SvnImport {
	my $val; 
	my $url;
	my $username;
	my $password;
	my $log_msg;

	$val = $app->run_prompt(
			'Enter SVN repository',
			['url','username','password','log_msg'],
			{ url => ['SVN repository URL', 'string', 'http://'],
			username => ['Username', 'string', ''],
			password => ['Password', 'password', ''],
			log_msg => ['Log message', 'string', 'Initial log message.']
			}
			);
	if ($val) {
		($url,$username,$password,$log_msg) = @$val;
		if (system ("svn import --username $username --password $password --message $log_msg $dir $url &>/dev/null")) {
			$app->error_dialog("Failed to checkout SVN repository $url!");
		}
	}
	else {
		&is_wc;
	}


}


sub on_SvnCommit {

	my $log_msg;
	my $val;

	if ( $val = $app->run_prompt('Enter log message', ['message'], { message => ['Log message', 'string', '']})) {
		($log_msg) = @$val;

		open(OUT,"svn stat \"$dir\" 2>&1|") ;
		while (<OUT>) {
			s/\n//;
			if (/^\?/) {
				my $add = substr ("$_",7);
				if (system ("svn add $add &>/dev/null")) {
					$app->error_dialog("Failed commit changes to SVN repository!");
				}
			}
			if (/^\!/) {
				my $del = substr ("$_",7);
				if (system ("svn del $del &>/dev/null")) {
					$app->error_dialog("Failed commit changes to SVN repository!");
				}
			}
		}

		if (system ("svn ci -m $log_msg $dir &>/dev/null")) {
			$app->error_dialog("Failed commit changes to SVN repository!");
		}
		else {
			$app->message('Commit successfull.');
		}
	}


}

sub on_SvnUpdate {
	if (system ("svn up $dir &>/dev/null")) {
		$app->error_dialog("Failed update working copy!");
	}
	else {
		$app->RBIndex();
		$app->Reload();
		$app->message('Update successfull.');
	}

}

1;
